# coding=utf-8
__all__ = ['StreamRegularDict', 'StreamWebDict', 'StreamDataframeDict']

import re
import urllib
import urllib.request
import sys, os, json, getopt
#import dask.dataframe as ddf
import queue
import pickle
import CommonUtils

header = {"User-Agent" : "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.7.62 Version/11.01"}

class StreamResDict():
    def __init__():
        pass

    def readline(self):
        pass

    def __del__(self):
        pass


class StreamRegularDict(StreamResDict):
    '''
    把文件中的内容，以行为单位，转为python字典
    '''
    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls)
        # obj = object.__new__(cls, *args, **kwargs)
        # 这里的object.__new__(cls, *args, **kwargs) 等价于super(Fun, cls).__new__(cls, *args, **kwargs)

        obj.filename = kwargs['filename']
        obj.f = open(obj.filename)
        if not obj.f:
            return None

        obj.emptyDict = {}
        regular_ = re.findall(r"(\?P\<)(\w*)(\>)", kwargs['regular'])
        for item in regular_:
            obj.emptyDict[item[1]] = ''

        obj.regular = re.compile(kwargs['regular'], re.IGNORECASE)

        return obj


    def __del__(self):
        self.f.close()


    def readline(self):
        line_ = self.f.readline()
        if not line_:
            return 1, {}

        dict_ = self.emptyDict.copy()
        status = 2
        result = re.finditer(self.regular, line_)
        for m_ in result:
            status = 0
            d_ = m_.groupdict()
            for key, value in d.items:
                dict_[key] = value

        return status, dict_



class StreamWebDict(StreamResDict):
    '''
    从Web上获取内容，JSON格式，以行为单位，转为python字典
    '''
    def __init__(url, req_parameters={}, access_token='', emptyDict={}):
        self.emptyDict = emptyDict

        self.url = url
        self.parameters = req_parameters
        self.parameters['access_token'] = access_token
        self.data = urllib.parse.urlencode(self.parameters).encode("utf-8")
        req = urllib.request.Request(self.url, data=self.data, headers=header)
        response = urllib.request.urlopen(req)
        jsonText = response.read().decode("utf-8")

        self.jsonObjs = json.loads(jsonText)
        self.curPos = 0

    def __del__(self):
        pass

    def readline(self):
        dict_ = self.emptyDict.copy()

        try:
            result = self.jsonObjs[self.curPos]
            self.curPos += 1
        except:
            return 1, {}

        for key, value in result:
            dict_[key] = value

        return 0, dict_



class StreamDataframeDict(StreamResDict):
    '''
    从Dataframe上获取内容，以行为单位，转为python字典。
    Dataframe可以来源于Pandas，Dask
    '''

    '''
import dask.dataframe as dd
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [3, 4, 5]},
                   index=['a', 'b', 'c'])
ddf = dd.from_pandas(df, npartitions=2)
ddf
    '''
    def __init__(self, df, emptyDict={}):
        self.emptyDict = emptyDict
        self.df = df
        # iterrows是Dataframe，dask.dataframe都支持的数据遍历方法
        self.row_iterator = df.iterrows()

    def readline(self):
        try:
            index, result = next(self.row_iterator)
        except:
            return 1, {}

        data_dict = result.to_dict()
        if self.emptyDict:
            dict_ = self.emptyDict.copy()
            for key, value in data_dict.items():
                dict_[key] = value
            return 0, dict_
        else:
            return 0, data_dict


class StreamMongodbDict(StreamResDict):
    '''
    从Mongodb上获取内容，以行为单位，转为python字典。
    '''
    def __init__(self, url='mongodb://localhost:27017/', db='', col_name='', emptyDict={}):
        myclient = pymongo.MongoClient()
        mydb = myclient[db]
        mycol = mydb[col_name]
        mongo_collection = mycol.find()
        self.emptyDict = emptyDict
        self.mongo_collection = mongo_collection
        self.row_iterator = mongo_collection.iterrows()

    def readline(self):
        dict_ = self.emptyDict.copy()

        try:
            index, data_dict = next(self.row_iterator)
        except:
            return 1, {}

        if self.emptyDict:
            for key, value in data_dict.items():
                dict_[key] = value
            return 0, dict_
        else:
            return 0, data_dict


class StreamQueueDict(StreamResDict):
    '''
    从Queue获取内容，以行为单位，转为python字典。
    '''
    def __init__(self, data_queue=None, timeoutSeconds=60*60*24*30, times_=3):
        self.timeoutSeconds = timeoutSeconds
        self.times_ = 3
        if data_queue:
            self.data_queue = queue.Queue()
        else:
            self.data_queue = data_queue

    def readline(self):
        for i in range(self.times_):
            try:
                dict_ = self.data_queue.get(timeout=timeoutSeconds)
                if isinstance(dict_, str):
                    dict_ = CommonUtils.tryLeval(dict_, {})
                return dict_
            except (queue.Empty):
                pass
            except (EOFError, BrokenPipeError):
                return None


if __name__ == '__main__':
    selectmatch = r"(?!')*\bfrom\b\s+\b(?P<table_name>\w+)\b\s*\b(?P<table_sn>\w*)\b(?!')*"                 #匹配select语句中的表名和表名的简写
    insertmatch = r"(?!')*\binsert\b\s+\binto\b\s+\b(?P<table_name>\w+)\b\s\b(?P<table_sn>\w+)\b(?!')*"    #匹配insert语句中的表名和表名的简写
    updatematch = r"(?!')*\bupdate\b\s+\b(?P<table_name>\w+)\b\s+\b(?P<table_sn>\w+)(?!')+"                 #匹配insert语句中的表名和表名的简写
    regular = r'''<td>(?P<number>\d+)</td>.*?<td><a>(?P<name>\w+)</a></td'''

    import sample_data
    filename = sample_data.get_data('yaml_example.yaml')
    srd = StreamRegularDict(filename=filename, regular=regular)
    while True:
        status, str_ = srd.readline()
        if not str_:
            break
        print (str(status), str_)
